<template>
  <div>
    <div class="filter-box">
      <el-card shadow="never">
        <div class="filter-container">
          <el-select
            v-model="query.library_id"
            placeholder="选择图书馆"
            clearable
            style="width: 200px"
            class="filter-item"
            @change="handleLibraryChange"
          >
            <el-option
              v-for="item in libraryOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
          <el-select
            v-model="query.floor_id"
            placeholder="选择楼层"
            clearable
            style="width: 200px"
            class="filter-item"
            @change="handleFloorChange"
          >
            <el-option
              v-for="item in floorOptions"
              :key="item.id"
              :label="item.floor_number"
              :value="item.id"
            />
          </el-select>
          <el-select
            v-model="query.area_id"
            placeholder="选择区域"
            clearable
            style="width: 200px"
            class="filter-item"
            @change="handleFilterChange"
          >
            <el-option
              v-for="item in areaOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd"
            style="width: 350px"
            class="filter-item"
            @change="handleDateRangeChange"
          />
          <el-button type="primary" icon="el-icon-search" class="filter-item" @click="fetchData">查询</el-button>
          <el-button type="success" icon="el-icon-download" class="filter-item" @click="handleExport">导出</el-button>
        </div>
      </el-card>
    </div>

    <div class="chart-container">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card shadow="never" class="chart-card">
            <div slot="header" class="clearfix">
              <span>每日预约统计</span>
            </div>
            <div ref="dailyChart" class="chart"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card shadow="never" class="chart-card">
            <div slot="header" class="clearfix">
              <span>预约状态分布</span>
            </div>
            <div ref="statusChart" class="chart"></div>
          </el-card>
        </el-col>
      </el-row>
      
      <el-row :gutter="20" style="margin-top: 20px;">
        <el-col :span="12">
          <el-card shadow="never" class="chart-card">
            <div slot="header" class="clearfix">
              <span>时段预约分布</span>
            </div>
            <div ref="timeSlotChart" class="chart"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card shadow="never" class="chart-card">
            <div slot="header" class="clearfix">
              <span>区域预约分布</span>
            </div>
            <div ref="areaChart" class="chart"></div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <el-card shadow="never" class="table-card">
      <div slot="header" class="clearfix">
        <span>热门座位排行</span>
      </div>
      <el-table
        :data="hotSeats"
        border
        stripe
        style="width: 100%"
        max-height="400px"
      >
        <el-table-column align="center" label="排名" width="80">
          <template slot-scope="scope">
            <el-tag :type="scope.$index < 3 ? 'danger' : 'info'" size="medium">{{ scope.$index + 1 }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column align="center" label="图书馆" prop="library_name" />
        <el-table-column align="center" label="楼层" prop="floor_number" />
        <el-table-column align="center" label="区域" prop="area_name" />
        <el-table-column align="center" label="座位" prop="seat_name" />
        <el-table-column align="center" label="预约次数" prop="count" width="120">
          <template slot-scope="scope">
            <el-progress :percentage="Math.round(scope.row.count / maxSeatCount * 100)" :format="() => scope.row.count" />
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>

<script>
import { http } from '@/api'
import * as echarts from 'echarts'

export default {
  name: 'ReservationStatistics',
  data() {
    return {
      query: {
        library_id: undefined,
        floor_id: undefined,
        area_id: undefined,
        start_date: undefined,
        end_date: undefined
      },
      dateRange: [],
      libraryOptions: [],
      floorOptions: [],
      areaOptions: [],
      dailyData: [],
      statusData: [],
      timeSlotData: [],
      areaData: [],
      hotSeats: [],
      maxSeatCount: 0,
      charts: {
        dailyChart: null,
        statusChart: null,
        timeSlotChart: null,
        areaChart: null
      },
      loading: false
    }
  },
  mounted() {
    this.getLibraryOptions()
    
    // 设置默认日期范围为最近30天
    const end = new Date()
    const start = new Date()
    start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
    this.dateRange = [this.formatDate(start), this.formatDate(end)]
    this.query.start_date = this.formatDate(start)
    this.query.end_date = this.formatDate(end)
    
    // 初始化图表
    this.$nextTick(() => {
      this.initCharts()
      window.addEventListener('resize', this.resizeCharts)
    })
    
    // 获取数据
    this.fetchData()
  },
  beforeDestroy() {
    // 销毁图表实例，避免内存泄漏
    Object.keys(this.charts).forEach(key => {
      if (this.charts[key]) {
        this.charts[key].dispose()
        this.charts[key] = null
      }
    })
    
    // 移除窗口大小变化监听
    window.removeEventListener('resize', this.resizeCharts)
  },
  methods: {
    formatDate(date) {
      const d = new Date(date)
      const year = d.getFullYear()
      const month = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    },
    getLibraryOptions() {
      http.libraries.list().then(response => {
        this.libraryOptions = response.data
      })
    },
    getFloorOptions() {
      this.floorOptions = []
      this.query.floor_id = undefined
      this.areaOptions = []
      this.query.area_id = undefined
      
      if (this.query.library_id) {
        http.libraryFloors.list({ library_id: this.query.library_id }).then(response => {
          this.floorOptions = response.data
        })
      }
    },
    getAreaOptions() {
      this.areaOptions = []
      this.query.area_id = undefined
      
      if (this.query.floor_id) {
        http.libraryAreas.list({ floor_id: this.query.floor_id }).then(response => {
          this.areaOptions = response.data
        })
      }
    },
    handleLibraryChange() {
      this.getFloorOptions()
      this.fetchData()
    },
    handleFloorChange() {
      this.getAreaOptions()
      this.fetchData()
    },
    handleFilterChange() {
      this.fetchData()
    },
    handleDateRangeChange(val) {
      if (val && val.length === 2) {
        this.query.start_date = val[0]
        this.query.end_date = val[1]
        this.fetchData()
      } else {
        this.query.start_date = undefined
        this.query.end_date = undefined
      }
    },
    fetchData() {
      this.loading = true
      
      // 获取统计数据
      http.reservations.getStats(this.query).then(response => {
        const data = response.data
        
        // 每日预约数据
        this.dailyData = data.daily || []
        
        // 状态分布数据
        this.statusData = data.status || []
        
        // 时段分布数据
        this.timeSlotData = data.timeSlot || []
        
        // 区域分布数据
        this.areaData = data.area || []
        
        // 热门座位数据
        this.hotSeats = data.hotSeats || []
        if (this.hotSeats.length > 0) {
          this.maxSeatCount = Math.max(...this.hotSeats.map(item => item.count))
        }
        
        // 更新图表
        this.initDailyChart()
        this.initStatusChart()
        this.initTimeSlotChart()
        this.initAreaChart()
        
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    initCharts() {
      this.charts.dailyChart = echarts.init(this.$refs.dailyChart)
      this.charts.statusChart = echarts.init(this.$refs.statusChart)
      this.charts.timeSlotChart = echarts.init(this.$refs.timeSlotChart)
      this.charts.areaChart = echarts.init(this.$refs.areaChart)
    },
    initDailyChart() {
      if (!this.charts.dailyChart) return
      
      const xAxisData = this.dailyData.map(item => item.date)
      const seriesData = this.dailyData.map(item => item.count)
      
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: xAxisData,
          axisLabel: {
            rotate: 45,
            interval: Math.floor(xAxisData.length / 10)
          }
        },
        yAxis: {
          type: 'value',
          minInterval: 1
        },
        series: [
          {
            name: '预约数量',
            type: 'line',
            data: seriesData,
            smooth: true,
            symbol: 'circle',
            symbolSize: 6,
            itemStyle: {
              color: '#409EFF'
            },
            lineStyle: {
              width: 3
            },
            areaStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  { offset: 0, color: 'rgba(64, 158, 255, 0.7)' },
                  { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
                ]
              }
            }
          }
        ]
      }
      
      this.charts.dailyChart.setOption(option)
    },
    initStatusChart() {
      if (!this.charts.statusChart) return
      
      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          right: 10,
          top: 'center',
          data: this.statusData.map(item => item.name)
        },
        series: [
          {
            name: '预约状态',
            type: 'pie',
            radius: ['50%', '70%'],
            avoidLabelOverlap: false,
            label: {
              show: false,
              position: 'center'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '18',
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            data: this.statusData.map(item => {
              return {
                name: item.name,
                value: item.count,
                itemStyle: {
                  color: this.getStatusColor(item.status)
                }
              }
            })
          }
        ]
      }
      
      this.charts.statusChart.setOption(option)
    },
    initTimeSlotChart() {
      if (!this.charts.timeSlotChart) return
      
      const xAxisData = this.timeSlotData.map(item => item.time_slot)
      const seriesData = this.timeSlotData.map(item => item.count)
      
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: xAxisData,
          axisLabel: {
            interval: 0,
            rotate: 45
          }
        },
        yAxis: {
          type: 'value',
          minInterval: 1
        },
        series: [
          {
            name: '预约数量',
            type: 'bar',
            data: seriesData,
            barWidth: '40%',
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#83bff6' },
                { offset: 0.5, color: '#188df0' },
                { offset: 1, color: '#188df0' }
              ])
            }
          }
        ]
      }
      
      this.charts.timeSlotChart.setOption(option)
    },
    initAreaChart() {
      if (!this.charts.areaChart) return
      
      // 按区域分组数据
      const areaGroups = {}
      this.areaData.forEach(item => {
        if (!areaGroups[item.area_name]) {
          areaGroups[item.area_name] = {
            name: item.area_name,
            count: 0,
            children: []
          }
        }
        areaGroups[item.area_name].count += item.count
        areaGroups[item.area_name].children.push({
          name: item.seat_name,
          value: item.count
        })
      })
      
      const data = Object.values(areaGroups).map(item => {
        return {
          name: item.name,
          value: item.count,
          children: item.children
        }
      })
      
      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{b}: {c}'
        },
        series: [
          {
            name: '区域分布',
            type: 'treemap',
            visibleMin: 1,
            label: {
              show: true,
              formatter: '{b}'
            },
            upperLabel: {
              show: true,
              height: 30
            },
            itemStyle: {
              borderColor: '#fff'
            },
            levels: [
              {
                itemStyle: {
                  borderColor: '#777',
                  borderWidth: 0,
                  gapWidth: 1
                },
                upperLabel: {
                  show: false
                }
              },
              {
                itemStyle: {
                  borderColor: '#555',
                  borderWidth: 5,
                  gapWidth: 1
                },
                emphasis: {
                  itemStyle: {
                    borderColor: '#ddd'
                  }
                }
              },
              {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                  borderWidth: 5,
                  gapWidth: 1,
                  borderColorSaturation: 0.6
                }
              }
            ],
            data: data
          }
        ]
      }
      
      this.charts.areaChart.setOption(option)
    },
    getStatusColor(status) {
      switch (status) {
        case 'pending':
          return '#E6A23C'
        case 'confirmed':
          return '#409EFF'
        case 'completed':
          return '#67C23A'
        case 'cancelled':
          return '#909399'
        case 'expired':
          return '#F56C6C'
        default:
          return '#909399'
      }
    },
    resizeCharts() {
      Object.keys(this.charts).forEach(key => {
        if (this.charts[key]) {
          this.charts[key].resize()
        }
      })
    },
    handleExport() {
      this.loading = true
      http.reservations.exportStatistics(this.query).then(response => {
        const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        
        const now = new Date()
        const year = now.getFullYear()
        const month = String(now.getMonth() + 1).padStart(2, '0')
        const day = String(now.getDate()).padStart(2, '0')
        const hour = String(now.getHours()).padStart(2, '0')
        const minute = String(now.getMinutes()).padStart(2, '0')
        
        link.download = `预约统计_${year}${month}${day}_${hour}${minute}.xlsx`
        link.click()
        URL.revokeObjectURL(link.href)
        this.loading = false
      }).catch(() => {
        this.loading = false
        this.$message.error('导出失败')
      })
    }
  }
}
</script>

<style scoped lang="scss">
.filter-box {
  margin-bottom: 20px;
}

.filter-container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  
  .filter-item {
    margin-right: 10px;
    margin-bottom: 10px;
  }
}

.chart-container {
  margin-bottom: 20px;
}

.chart-card {
  margin-bottom: 20px;
  
  .chart {
    height: 350px;
  }
}

.table-card {
  margin-bottom: 20px;
}
</style>
